package com.atguigu.lease.admin.service.impl;


import com.atguigu.lease.admin.service.LoginService;
import com.atguigu.lease.admin.service.SystemUserService;
import com.atguigu.lease.common.consts.RedisConstant;
import com.atguigu.lease.common.consts.StgyAdminConstant;
import com.atguigu.lease.common.util.JwtUtil;
import com.atguigu.lease.model.bean.SystemUser;
import com.atguigu.lease.model.vo.system.CaptchaVo;
import com.atguigu.lease.model.vo.system.LoginVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wf.captcha.ArithmeticCaptcha;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    SystemUserService systemUserService;

    @Override
    public CaptchaVo getCaptcha() {
        //1、生成验证码图片
        //生成算术验证码
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48, 3);
        //2、缓存验证码的算术结果
        String text = captcha.text();
        // 每个客户端的请求 应该生成唯一的键
        String token = UUID.randomUUID().toString().replace("-", "");
        stringRedisTemplate.opsForValue().set(RedisConstant.ADMIN_LOGIN_CAPTCHA_PREFIX + token, text, 15, TimeUnit.MINUTES);

        //3、返回验证码图片 和验证码字符串缓存的键（自定义vo类）
        CaptchaVo captchaVo = new CaptchaVo();
        captchaVo.setImage(captcha.toBase64());
        captchaVo.setKey(token);
        return captchaVo;
    }

    @Override
    public String login(LoginVo loginVo) {
        //1、获取验证码 校验
        String code = loginVo.getCaptchaCode();
        if (StringUtils.isEmpty(code)) {
            throw new RuntimeException("未提交验证码");
        }
        //获取redis中缓存的验证码
        String captchaKey = RedisConstant.ADMIN_LOGIN_CAPTCHA_PREFIX + loginVo.getCaptchaKey();
        //redisTemplate使用哪个存的 就是用哪个取(StringRedisTemplate存 就必须使用它来取)
        String cacheCaptcha = stringRedisTemplate.opsForValue()
                .get(captchaKey);
        if (StringUtils.isEmpty(cacheCaptcha)) {
            throw new RuntimeException("验证码已失效");
        }

        if (!code.equals(cacheCaptcha)) {
            //验证码输入错误
            throw new RuntimeException("验证码输入错误");
        }
        //删除redis中的缓存验证码
        stringRedisTemplate.delete(captchaKey);

        //2、根据账号查询管理员信息
        if (StringUtils.isEmpty(loginVo.getUsername()) || StringUtils.isEmpty(loginVo.getPassword())) {
            throw new RuntimeException("账号密码不能为空!!");
        }

        String username = loginVo.getUsername();
        SystemUser systemUser = systemUserService.getOne(Wrappers.lambdaQuery(SystemUser.class)
                .eq(SystemUser::getUsername, username));
        if (systemUser == null) {
            throw new RuntimeException("账号不存在");
        }
        //3、校验密码
        //对客户端提交的明文密码 加密(加密方式必须和新增管理员时 一样！！！)
        String encodePwd = DigestUtils.md5Hex(loginVo.getPassword());//
        if (!encodePwd.equals(systemUser.getPassword())) {//使用明文加密的结果 和数据库查询到的密文进行比较
            throw new RuntimeException("密码错误");
        }
        //4、校验管理员状态
        if (!systemUser.getStatus().equals(1)) {
            throw new RuntimeException("账号被禁用");
        }
        //5、构建jwttoken
        Map<String, String> map = new HashMap<>();
        map.put(StgyAdminConstant.JWT_TOKEN_USER_ID, systemUser.getId().toString());
        map.put(StgyAdminConstant.JWT_TOKEN_AVATAR_URL, systemUser.getAvatarUrl());
        map.put(StgyAdminConstant.JWT_TOKEN_USER_NAME, systemUser.getName());
        return JwtUtil.createToken(map);
    }
}
